;(function (root, factory) {
  typeof exports === 'object' && typeof module !== 'undefined'
      ? module.exports = factory() :
      typeof define === 'function' && define.amd ? define(factory) :
          (root.iNotify = factory());
}(this, function (root, undefined) {
  var repeatableEffects = ['flash', 'scroll'],
      defaultNotification = {
        title: "通知！",
        body: '您来了一条新消息',
        openurl: ''
      },
      iconURL = "";

  function iNotify(config) {
    if (config) {
      this.init(config);
    }
  }

  iNotify.prototype = {
    init: function (config) {
      if (!config) {
        config = {};
      }
      this.interval = config.interval || 200; //响应时长
      this.effect = config.effect || 'flash'; //效果
      this.title = config.title || document.title; //标题
      this.message = config.message || this.title; //原来的标题
      this.onclick = config.onclick || this.onclick; //点击事件
      this.openurl = config.openurl || this.openurl; //点击事件
      this.updateFavicon = config.updateFavicon || {
        id: "favicon",
        textColor: "#fff",
        backgroundColor: "#2F9A00"
      }
      this.audio = config.audio || '';
      this.favicon = getFavicon(this.updateFavicon);
      this.favicon = this.favicon;
      this.cloneFavicon = this.favicon.cloneNode(true);
      defaultNotification.icon = iconURL = (config.notification
          && config.notification.icon) ? config.notification.icon : (config.icon
          ? config.icon : this.favicon.href);
      this.notification = config.notification || defaultNotification;
      //初始化生成声音文件节点
      if (this.audio && this.audio.file) {
        this.setURL(this.audio.file)
      }
      return this;
    },
    render: function () {
      switch (this.effect) {
        case 'flash':
          document.title = (this.title === document.title) ? this.message
              : this.title;
          break;
        case 'scroll':
          document.title = document.title.slice(1);
          if (0 === document.title.length) {
            document.title = this.message;
          }
          break;
      }
    },
    setURL: function (url) {
      if (url) {
        if (this.audioElm) {
          this.audioElm.remove();
        }
        this.audioElm = createAudio(url);
        document.body.appendChild(this.audioElm);
      }
      return this;
    },
    loopPlay: function () {
      this.setURL();
      this.audioElm.loop = true;
      this.player();
      return this;
    },
    stopPlay: function () {
      this.audioElm && (this.audioElm.loop = false, this.audioElm.pause());
      return this;
    },
    //播放声音
    player: function () {
      var adi = this.audio.file,
          source = null;
      if (!this.audio || !this.audio.file) {
        return;
      }
      if (!this.audioElm) {
        this.audioElm = createAudio(this.audio.file);
        document.body.appendChild(this.audioElm)
      }
      this.audioElm.play();
      return this;
    },
    notify: function (json) {
      var nt = this.notification;
      var url = json.openurl ? json.openurl : this.openurl;
      var onclick = json.onclick ? json.onclick : this.onclick;
      if (window.Notification) {
        if (json) {
          nt = jsonArguments(json, nt);
        } else {
          nt = defaultNotification;
        }
        var n = new Notification(nt.title, {
          icon: json.icon ? json.icon : iconURL,
          body: nt.body
        });
        n.onclick = function () {
          (onclick && typeof (onclick) === "function") && onclick(n);
          url && window.open(url);
        }
      }
      return this;
    },
    //是否许可弹框通知
    isPermission: function () {
      return window.Notification && Notification.permission === "granted" ? true
          : false;
    },
    //设置标题
    setTitle: function (str) {
      if (str === true) {
        if (0 <= repeatableEffects.indexOf(this.effect)) {
          return this.addTimer();
        }
      } else if (str) {
        this.message = str,
            this.addTimer();
      } else {
        this.clearTimer(),
            this.title = this.title;
      }
      return this;
    },
    //设置时间间隔
    setInterval: function (num) {
      if (num) {
        this.interval = num,
            this.addTimer();
      }
      return this;
    },
    //设置网页Icon
    setFavicon: function (num) {
      if (!num && num !== 0) {
        return this.faviconClear();
      }
      var oldicon = document.getElementById('new' + this.updateFavicon.id)
      if (this.favicon) {
        this.favicon.remove();
      }
      if (oldicon) {
        oldicon.remove();
      }
      changeFavicon(num, this.updateFavicon)
      return this;
    },
    //添加计数器
    addTimer: function () {
      this.clearTimer();
      if (0 <= repeatableEffects.indexOf(this.effect)) {
        this.timer = setInterval(this.render.bind(this), this.interval);
      }
      return this;
    },
    //清除Icon
    faviconClear: function () {
      var newicon = document.getElementById('new' + this.updateFavicon.id),
          head = document.getElementsByTagName('head')[0],
          ficon = document.querySelectorAll('link[rel~=shortcut]');
      newicon && newicon.remove();
      if (ficon.length > 0) {
        for (var i = 0; i < ficon.length; i++) {
          ficon[i].remove()
        }
      }
      head.appendChild(this.cloneFavicon);
      iconURL = this.cloneFavicon.href;
      this.favicon = this.cloneFavicon;
      return this;
    },
    //清除计数器
    clearTimer: function () {
      clearInterval(this.timer);
      document.title = this.title;
      return this;
    }
  };

  // 获取 favicon
  function getFavicon(setting) {
    var ic = document.querySelectorAll('link[rel~=shortcut]')[0];
    if (!ic) {
      ic = changeFavicon('O', setting);
    }
    return ic;
  }

  function createAudio(url) {
    var audioElm = document.createElement('audio'),
        source;
    if (isArray(url) && url.length > 0) {
      for (var i = 0; i < url.length; i++) {
        source = document.createElement('source');
        source.src = url[i];
        source.type = 'audio/' + getExtension(url[i]);
        audioElm.appendChild(source);
      }
    } else {
      audioElm.src = url;
    }
    return audioElm;
  }

  function isArray(value) {
    return Object.prototype.toString.call(value) === '[object Array]';
  }

  function changeFavicon(num, settings) {
    var canvas = document.createElement('canvas'),
        img = document.createElement('img'),
        head = document.getElementsByTagName('head')[0],
        linkTag = document.createElement('link'),
        ctx;

    canvas.height = canvas.width = 32;
    ctx = canvas.getContext('2d');
    ctx.fillStyle = settings.backgroundColor;
    ctx.fillRect(0, 0, 32, 32);

    ctx.textAlign = "center";
    ctx.font = '22px "helvetica", sans-serif';
    ctx.fillStyle = settings.textColor;
    ctx.fillText(num, 16, 24);

    //生成到
    linkTag.setAttribute('rel', 'shortcut icon');
    linkTag.setAttribute('type', 'image/x-icon');
    linkTag.setAttribute('id', 'new' + settings.id);
    linkTag.setAttribute('href', canvas.toDataURL('image/png'));
    iconURL = canvas.toDataURL('image/png');
    return head.appendChild(linkTag);
  };

  //获取文件后缀
  function getExtension(file_name) {
    return file_name.match(/\.([^\.]+)$/)[1];
  }

  function jsonArguments(news, olds) {
    for (var a in olds) {
      if (news[a]) {
        olds[a] = news[a]
      }
    }
    return olds
  }

  //提醒是否添加chrome通知
  if (window.Notification && window.Notification.permission !== "granted") {
    window.Notification.requestPermission();
  }
  return iNotify;
}));
